﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ElevatorAPI;

namespace ElevatorSimulator
{
    class Program
    {
        //metrics
        static ushort TotalPeopleWaited = 0;
        static ushort TotalPeopleRode = 0;
        static uint TotalMoves = 0;
        static DateTime ExerciseStart = DateTime.MinValue;
        static DateTime ExerciseEnd = DateTime.MinValue;
        static ElevatorController.Controller_Sample controller;

        static void Main(string[] args)
        {
            //List<Floor> BuildingFloors = new List<Floor>()
            //    {
            //        new Floor(1){Name="Lobby"},
            //        new Floor(2){Name = "Mail Room"},
            //        new Floor(3){Name = "Legal"},
            //        new Floor(4){Name = "HR"},
            //        new Floor(5){Name = "Testing"},
            //        new Floor(6){Name = "Customer Service"},
            //        new Floor(7){Name = "R&D"},
            //        new Floor(8){Name = "Engineering"},
            //        new Floor(9){Name = "Accounting"},
            //        new Floor(10){Name = "Executives"}
            //    };

            //BuildingFloors = BuildingFloors.OrderByDescending(f => f.Number).ToList();

            //create instance of students own controller.
            // controller = new ElevatorController.Controller_CHodge(BuildingFloors);

            //foreach (Floor f in controller.Building.Floors)
            //{
            //    f.OnPersonExitedElevator += new Floor.PersonExitedElevatorHandler(f_PersonExitedElevator);
            //    f.OnPersonWaitingForElevator += new Floor.PersonWaitingForElevatorHandler(f_PersonWaitingForElevator);
            //    f.OnCallButtonPressed += new Floor.CallButtonPressedHandler(f_ElevatorCalled);
            //    f.OnPersonEnteredElevator += new Floor.PersonEnteredElevatorHandler(f_PersonEnteredElevator);
            //}

            //wireup all events to get all moves counter
            //controller.Building.Elevator.OnElevatorDoorsOpened += new ElevatorAPI.Elevator.ElevatorDoorsOpenedHandler(Elevator_ElevatorDoorsOpened);
            //controller.Building.Elevator.OnElevatorStopped += new ElevatorAPI.Elevator.ElevatorStoppedHandler(Elevator_ElevatorStopped);
            //controller.Building.Elevator.OnElevatorStarted += new ElevatorAPI.Elevator.ElevatorStartedHandler(Elevator_ElevatorStarted);
            //controller.Building.Elevator.OnElevatorFloorButtonPressed += new ElevatorAPI.Elevator.ElevatorFloorButtonPressedHandler(Elevator_ElevatorFloorButtonPressed);
            //controller.Building.Elevator.OnElevatorDoorsClosed += new ElevatorAPI.Elevator.ElevatorDoorsClosedHandler(Elevator_ElevatorDoorsClosed);
            //controller.Building.Elevator.OnElevatorMoved += new ElevatorAPI.Elevator.ElevatorMovedHandler(Elevator_ElevatorMoved);
                        
            
            //Console.WriteLine("Student Elevator Controller Exercise 1");
            //Console.WriteLine("=======================================");
            //Console.WriteLine("Controller loaded for: " + controller.StudentsName);
            //Console.WriteLine("Elevator Started at " + controller.Building.Elevator.CurrentFloor.Name + "(" + controller.Building.Elevator.CurrentFloor.Number + ") with its doors " + controller.Building.Elevator.DoorState);
            //Console.WriteLine("=======================================");
            
            //ExerciseStart = DateTime.Now;

            //Console.WriteLine("Scenario Loaded:");
            //Console.WriteLine("1. person to top floor wanting to go to bottom floor.");
            //controller.Building.Floors.First(f => f.Number == 10).AddPersonToFloorWaitingForElevator(new Person() { Name = "PersonA", DestinationFloor = controller.Building.Floors.First(f => f.Number == 1) });

            //Console.WriteLine("2. person going from 6 to 2");
            //controller.Building.Floors.First(f => f.Number == 6).AddPersonToFloorWaitingForElevator(new Person() { Name = "PersonB", DestinationFloor = controller.Building.Floors.First(f => f.Number == 2) });

            //Console.WriteLine("3. person to same floor as start");
            //controller.Building.Floors.First(f => f.Number == 4).AddPersonToFloorWaitingForElevator(new Person() { Name = "PersonC", DestinationFloor = controller.Building.Floors.First(f => f.Number == 4) });

            //Console.WriteLine("4. person going up"); ;
            //controller.Building.Floors.First(f => f.Number == 2).AddPersonToFloorWaitingForElevator(new Person() { Name = "PersonD", DestinationFloor = controller.Building.Floors.First(f => f.Number == 9) });

            //Console.WriteLine("5. person getting on at lobby.");
            //controller.Building.Floors.First(f => f.Number == 9).AddPersonToFloorWaitingForElevator(new Person() { Name = "PersonE", DestinationFloor = controller.Building.Floors.First(f => f.Number == 1) });

            //Console.WriteLine("=======================================");

            //Console.WriteLine("Start Students Elevator");
            //controller.Building.Elevator.Start();

            Console.ReadKey();
        }

        static void f_PersonEnteredElevator(Person PersonGettingOn, Floor FloorWaitingOn)
        {
            TotalMoves++;
            //Console.WriteLine("Person Entered Elevator " + PersonGettingOn.Name + " --- " + FloorWaitingOn.Name + " (" + FloorWaitingOn.Number + ")");
        }

        static void f_ElevatorCalled(object sender, Enumerations.ButtonPressed ButtonPressed)
        {
           // Console.WriteLine("Elevator Called to floor " + (sender as Floor).Name + "(" + (sender as Floor).Number + ")" + " - Going " + ButtonPressed.ToString());
            TotalMoves++;
        }

        static void Elevator_ElevatorStopped(object sender, Floor FloorStoppedOn)
        {
           // Console.WriteLine("Elevator Stopped on " + FloorStoppedOn.Name + " (" + FloorStoppedOn.Number + ")");
            TotalMoves++;

            //if (controller.Building.Elevator.Trajectory == Enumerations.ElevatorTrajectory.Idle &&
            //    controller.Building.Elevator.PeopleInside.Count==0 &&
            //    controller.Building.Floors.Where(f=>f.PeopleWaiting.Count>0).Count() == 0)
            //{
            //    ExerciseEnd = DateTime.Now;

            //    Console.WriteLine("--------------");
            //    Console.WriteLine("METRICS");
            //    Console.WriteLine("Total Time: " + (ExerciseEnd - ExerciseStart).TotalMilliseconds + "ms");
            //    Console.WriteLine("Total Waited: " + TotalPeopleWaited);
            //    Console.WriteLine("Total Rode: " + TotalPeopleRode);
            //    Console.WriteLine("Got all the passengers: " + (TotalPeopleRode == TotalPeopleWaited));
            //    Console.WriteLine("Total Actions Taken: " + TotalMoves);
            //    var result = (52081 - ((ExerciseEnd - ExerciseStart).TotalMilliseconds)) + (100 * ((TotalPeopleRode == TotalPeopleWaited) ? 1 : 0)) + (10 * (98 - TotalMoves));
            //    Console.WriteLine("Computed score: " + result );
            //    Console.ReadKey();
            //}
        }

        static void Elevator_ElevatorMoved(object sender, Floor FloorStoppedOn, Enumerations.ElevatorTrajectory MovementTrajectory)
        {
         //   Console.WriteLine("Elevator Moved to " + FloorStoppedOn.Name + " (" + FloorStoppedOn.Number + ") by going " + MovementTrajectory.ToString());
            TotalMoves++;
        }

        static void Elevator_ElevatorFloorButtonPressed(object sender, Floor FloorRequested)
        {
          //  Console.WriteLine("Person Pressed Floor Selection Button " + FloorRequested.Name + " (" + FloorRequested.Number + ")");
            TotalMoves++;
        }

        static void Elevator_ElevatorDoorsOpened(object sender, Floor FloorStoppedOn)
        {
           // Console.WriteLine("Elevator Doors Opened on " + FloorStoppedOn.Name + " (" + FloorStoppedOn.Number + ")");
            TotalMoves++;
        }

        static void Elevator_ElevatorDoorsClosed(object sender, Floor FloorStoppedOn)
        {
           // Console.WriteLine("Elevator Doors Closed on " + FloorStoppedOn.Name + " (" + FloorStoppedOn.Number + ")");
            TotalMoves++;
        }

        static void f_PersonWaitingForElevator(Person PersonGettingOn, Floor FloorWaitingOn)
        {
            TotalMoves++;
            TotalPeopleWaited++;
           // Console.WriteLine("Person Waiting For Elevator " + PersonGettingOn.Name + " --- " + FloorWaitingOn.Name + " (" + FloorWaitingOn.Number + ")");
        }

        static void f_PersonExitedElevator(Person PersonGettingOff, Floor FloorExitingOn)
        {
            TotalMoves++;
            TotalPeopleRode++;
           // Console.WriteLine("Person Exited Elevator " + PersonGettingOff.Name + " --- " + FloorExitingOn.Name + " (" + FloorExitingOn.Number + ")");
          //  Console.WriteLine("Person Completed their trip and exited the elevator." + PersonGettingOff.Name + " got off on floor " + FloorExitingOn.Name + "(" + FloorExitingOn.Number + ")." + " Person waited for elevator for " + PersonGettingOff.TotalWaitingTime.Value.TotalMilliseconds + "ms and rode for " + PersonGettingOff.TotalRidingTime.Value.TotalMilliseconds + "ms");
        }

        static void Elevator_ElevatorStarted(object sender)
        {
            Console.WriteLine("Elevator Started ");
            TotalMoves++;
        }
    }
}
